/**
 *
 */
package org.insia.smartposse.manager;

import java.io.Serializable;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.hibernate.HibernateException;
import org.insia.smartposse.form.ProfileForm;
import org.insia.smartposse.manager.iface.IManager;
import org.insia.smartposse.manager.list.FreelanceSkillsListManager;
import org.insia.smartposse.mapping.Users;
import org.insia.smartposse.mapping.dao.UsersDAO;

/**
 * @author cmougel
 *
 */
public class UserManager implements Serializable, IManager{

	private final static String STRING_TO_DATE = "yyyy-MM-dd";
	private final Users _user;
	private final UsersDAO _dao = new UsersDAO();

	/**
	 * Create UserManager with a login
	 *
	 * @param login the login of this user
	 */
	public UserManager(String login){
		if ("" != login){
			_user = _dao.getByLogin(login);
		} else {
			_user = null;
		}
	}

	/**
	 * Create UserManager from user
	 * @param user
	 */
	public UserManager(Users user){
			_user = user;
	}

	public UserManager() {
		_user = new Users();
	}

	public UserManager(Integer id) {
		_user = _dao.get(id);
	}

	/**
	 * @return Returns the id.
	 */
	public Integer getId() {
		return _user.getId();
	}

	/**
	 * @param id The id to set.
	 */
	public void setId(Integer id) {
		_user.setId(id);
	}

	/**
	 * @return Returns the login.
	 */
	public String getLogin() {
		return _user.getLogin();
	}

	/**
	 * @param login The login to set.
	 */
	public void setLogin(String login) {
		_user.setLogin(login);
	}

	/**
	 * @return Returns the password.
	 */
	public String getPassword() {
		if (null != _user){
			return _user.getPassword();
		} else {
			return null;
		}
	}

	/**
	 * set the password not encoding, for Hibernate
	 *
	 * @param password The password to set.
	 */
	public void setPassword(String password) {
		_user.setPassword(encodePassword(password));
	}

	/**
	 * Define if the User is Manager or not
	 *
	 * @param bool
	 */
	public void setManager(Boolean bool){
		_user.setManager(bool);
	}

	/**
	 * Say if the User is Manager or not
	 *
	 * @return manager or not
	 */
	public Boolean isManager(){
		return _user.isManager();
	}

	public Boolean getManager(){
		return _user.isManager();
	}


	/**
	 * Define if the User is Freelance or not
	 *
	 * @param bool
	 */
	public void setFreelance(Boolean bool){
		_user.setFreelance(bool);
	}

	/**
	 * Say if the User is Freelance or not
	 *
	 * @return freelance or not
	 */
	public Boolean isFreelance(){
		return _user.isFreelance();
	}

	public Boolean getFreelance(){
		return _user.isFreelance();
	}

	/**
	 *
	 *@return the FirstName
	 */
	public String getFirstName(){
		return _user.getFirstName();
	}

	/**
	 * Define the FirstName
	 *
	 * @param firstName
	 */
	public void setFirstName(String firstName){
		_user.setFirstName(firstName);
	}

	/**
	 *
	 * @return the LastName
	 */
	public String getLastName(){
		return _user.getLastName();
	}

	/**
	 * Define the LastName
	 * @param LastName
	 */
	public void setLastName(String LastName){
		_user.setLastName(LastName);
	}

	/**
	 * @return the Name of User
	 */
	public String getName(){
		if (null == getLastName() || null == getFirstName()){
			return null;
		} else {
			return getLastName() + ' ' + getFirstName();
		}
	}

	public String getCorrectDate(String s) {
		String regexpEn = "([0-9]{4})[/-]([0-9]{1,2})[/-]([0-9]{1,2})";
		String regexpFr = "([0-9]{1,2})[/-]([0-9]{1,2})[/-]([0-9]{4})";
		String ok = null;
		String[] arr = s.split("[/-]");
		if (s.matches(regexpEn)) {
			ok = arr[0] + "-" + arr[1] + "-"+ arr[2];
		}
		if (s.matches(regexpFr)) {
			ok = arr[2] + "-" + arr[1] + "-"+ arr[0];
		}
		return ok;
	}

	public String setCorrectDate(String s) {
		String regexpEn = "([0-9]{4})[/-]([0-9]{1,2})[/-]([0-9]{1,2})";
		String regexpFr = "([0-9]{1,2})[/-]([0-9]{1,2})[/-]([0-9]{4})";
		String ok = null;
		String[] arr = s.split("[/-]");
		if (s.matches(regexpEn)) {
			ok = arr[2] + "-" + arr[1] + "-"+ arr[0];
		}
		if (s.matches(regexpFr)) {
			ok = arr[2] + "-" + arr[1] + "-"+ arr[0];
		}
		return ok;
	}

	/**
	 * Define the birthday of the user
	 * @param bday
	 * @throws ParseException
	 */
	public void setBirthday(String bday) throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat(STRING_TO_DATE);
		_user.setBirthday(sdf.parse(getCorrectDate(bday)));
	}

	public String getBirthday() {
		SimpleDateFormat sdf = new SimpleDateFormat(STRING_TO_DATE);
		return setCorrectDate(sdf.format(_user.getBirthday()));
	}

	/**
	 * Define the email of the user
	 * @param email
	 */
	public void setEmail(String email) {
		_user.setEmail(email);
	}

	public String getEmail() {
		return _user.getEmail();
	}


	/**
	 * Define the website for the user
	 * @param website
	 */
	public void setWebsite(String website) {
		_user.setWebsite(website);
	}

	public String getWebsite() {
		return _user.getWebsite();
	}

	/**
	 * Define the description for the user
	 * @param desc
	 */
	public void setDescription(String desc) {
		_user.setDescription(desc);
	}

	public String getDescription() {
		return _user.getDescription();
	}

	/**
	 * Define the salary for the user
	 * @param salary
	 */
	public void setSalary(double salary) {
		_user.setSalary(salary);
	}

	public double getSalary() {
		return _user.getSalary();
	}

	/**
	 * Define the hidden/not-hidden of the user's email
	 * @param anonyme
	 */
	public void setEmailAnonyme(boolean anonyme) {
		_user.setEmailAnonyme(anonyme);
	}

	public Boolean getEmailAnonyme() {
		return _user.isEmailAnonyme();
	}

	public Boolean isEmailAnonyme() {
		return _user.isEmailAnonyme();
	}

	/**
	 * Test if the password is same
	 *
	 * @param pwd
	 * @throws EncodeException
	 */
	public boolean passwordOk(String pwd) {
		if (pwd != ""){
			return (encodePassword(pwd).equals(getPassword()));
		} else {
			return false;
		}
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see java.util.Date#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		boolean result = false;
		if (obj instanceof UserManager) {
			UserManager u = (UserManager) obj;
			result = u.getLogin().equals(this.getLogin());
		}
		return result;
	}

	/**
	 * Save the user inside UserHelper with the DAO
	 *
	 */
	public void save() {

		// No NULL in database
		if (null == _user.getAvatar()){
			_user.setAvatar("");
		}

		if (null == _user.getBirthday()){
			_user.setBirthday(new Date(0));
		}

		if (null == _user.getDescription()){
			_user.setDescription("");
		}

		if (null == _user.getEmail()){
			_user.setEmail("");
		}

		if (null == _user.getFirstName()){
			_user.setFirstName("");
		}

		if (null == _user.getLastName()){
			_user.setLastName("");
		}

		if (null == _user.getLanguage()){
			_user.setLanguage("");
		}

		if (null == _user.getLogin()){
			_user.setLogin("");
		}

		if (null == _user.getPassword()){
			_user.setPassword("");
		}

		if (null == _user.getWebsite()){
			_user.setWebsite("");
		}

		_dao.saveOrUpdate(_user);
	}


	private final static String INST = "SHA1";

	/**
	 * Encode the password for check it
	 *
	 * @param password
	 * @return password encoding
	 */
	private String encodePassword(String password) {
		 MessageDigest md5 = null;
		 try{
			 md5 = MessageDigest.getInstance(INST);
			 md5.update(password.getBytes());
			 return toHex(md5.digest());
		 } catch (NoSuchAlgorithmException nsae){
			 return "";
		 }
	 }

	 /**
	  * Read the digest and return a string
	  *
	  * @param digest
	  * @return the string encode
	  */
	 private String toHex(final byte digest[]){
		 final StringBuffer buf = new StringBuffer();
		 for (int i = 0; i < digest.length; i++){
			 buf.append(Integer.toHexString(digest[i] & 0xff));
		 }
		 return buf.toString();
	 }

	 /**
	  * @return his user save into
	  */
	public Users getUser() {
		return _user;
	}

	/**
	 * Return the list of Skill for the Freelance
	 *
	 * @return
	 */
	public FreelanceSkillsListManager getSkills(){
		if (isFreelance()){
			return new FreelanceSkillsListManager(_user.getFreelanceSkillsList());
		} else {
			throw new HibernateException("Only the Freelance must had Skill");
		}
	}

	public int getNbJobAccept(){
		if (isFreelance()){
			return _dao.nbJobAccept(this, _dao.getSession());
		} else {
			throw new HibernateException("Only the Freelance must had several Job Accept");
		}
	}

	public void populateLogin(ProfileForm form) throws ParseException {
		setLogin(form.getLogin());
		setPassword(form.getPassword());
	}

	public void populateProfile(ProfileForm form) throws ParseException {
		setFirstName(form.getFirstname());
		setLastName(form.getLastname());
		setBirthday(form.getBirthday());
		setEmail(form.getEmail());
		setWebsite(form.getWebsite());
		setDescription(form.getDescription());
		setSalary(form.getSalary());
		setEmailAnonyme(form.getEmailAnonyme());
		setFreelance(form.getFreelance());
		setManager(form.getManager());
	}

	public void setProfile(ProfileForm form) {
		form.setUserId(getId());
        form.setFirstname(getFirstName());
        form.setLastname(getLastName());
        form.setBirthday(getBirthday());
        form.setEmail(getEmail());
        form.setWebsite(getWebsite());
        form.setDescription(getDescription());
        form.setSalary(getSalary());
        form.setEmailAnonyme(getEmailAnonyme());
        form.setFreelance(isFreelance());
        form.setManager(isManager());
    }

}
